import Snake from "./snake"
import Food from "./food"
import ScorePanel from "./score-panel"

// 游戏主控制类，所有游戏逻辑都在此处
class GameControl {
  // 所有游戏操作对象（精灵）
  snake: Snake
  food: Food
  scorePanel: ScorePanel
  lastDirection: string = ''
  direction: string = ''
  constructor() {
    this.snake = new Snake()
    this.food = new Food()
    this.scorePanel = new ScorePanel()
    // this.init()
  }

  // 游戏初始化，并且运行游戏
  init() {
    // 按键输入响应
    // 注意：使用bind绑定this，防止传递回调函数时this被修改
    document.addEventListener('keydown', this.keydowmHandle.bind(this))
    // 蛇自动移动
    this.run()
  }

  keydowmHandle(event: KeyboardEvent) {
    this.direction = event.key
  }

  // 蛇自动移动
  run() {
    // 根据this.direction改变蛇的位置

    // 获取蛇的坐标
    let [x, y] = [this.snake.x, this.snake.y]

    //防止掉头
    const direction: Map<string, string> = new Map([
      ['ArrowUp', 'ArrowDown'],
      ['ArrowDown', 'ArrowUp'],
      ['ArrowLeft', 'ArrowRight'],
      ['ArrowRight', 'ArrowLeft'],
    ])

    if (this.snake.bodies.length >= 2 && direction.has(this.lastDirection) && direction.get(this.lastDirection) == this.direction) {
      // 发生掉头
      // 掰正方向
      this.direction = direction.get(this.direction) as string
    }

    // 蛇移动坐标计算
    // 上 ArrowUp
    // 下 ArrowDown
    // 左 ArrowLeft
    // 右 ArrowRight
    // 注意：IE浏览器为 Up Down Left Right
    switch (this.direction) {
      // 上
      case "ArrowUp":
        y -= 10
        break
      // 下
      case "ArrowDown":
        y += 10
        break
      // 左
      case "ArrowLeft":
        x -= 10
        break
      // 右
      case "ArrowRight":
        x += 10
        break
    }

    this.lastDirection = this.direction

    //撞墙判断(撞墙后可以穿墙，即位移到另一端出现)
    if (x < 0) {
      x = 290
    } else if (x > 290) {
      x = 0
    }

    if (y < 0) {
      y = 290
    } else if (y > 290) {
      y = 0
    }

    //吃到食物判断
    if (x === this.food.x && y == this.food.y) {
      console.log('吃到食物')
      //计分
      this.scorePanel.addScore()
      //修改食物位置
      this.food.change()
      //增加身体
      this.snake.addBody()
    }

    //修改蛇位置
    this.snake.x = x
    this.snake.y = y

    console.log(this.snake.x, this.snake.y)

    //判断是否吃到身体
    if (this.snake.checkEatBody()) {
      console.log('吃到身体')
      alert('GAME OVER')
      return
    }

    let speed = 300 - (this.scorePanel.level - 1) * 20 //速度。最大减少时间是9 * 20 = 180
    setTimeout(this.run.bind(this), speed)
  }
}

export default GameControl